package com.ruleengine.context.impl;

import org.apache.log4j.Logger;

import com.ruleengine.container.WorkflowContainerManager;
import com.ruleengine.context.IContextProperty;
import com.ruleengine.context.IExecuteIdFactory;
import com.ruleengine.context.IWorkflowConext;
import com.ruleengine.context.IWorkflowContextConstants;
import com.ruleengine.instruction.InstructionSet;
import com.ybt.configration.IYBTConfigration;
import com.ybt.configration.YBTRuntimeConfiguration;

/**
 * 工作流上下文工厂，用于创建工作流上下文.
 * 
 * @author wuxiao
 * 
 * Created on Apr 6, 2012
 */
public class WorkflowContextFactory {
    private static Logger logger = Logger
            .getLogger(WorkflowContextFactory.class);
    private static volatile WorkflowContextFactory factory;
    private IExecuteIdFactory idFactory;

    private WorkflowContextFactory() {
        String className = YBTRuntimeConfiguration.getInstance().getProperty(
                IYBTConfigration.EXECUTE_ID_FACTORY);
        try {
            Class c = Class.forName(className);
            idFactory = (IExecuteIdFactory) c.newInstance();
        } catch (Exception e) {
            throw new RuntimeException("load "
                    + IYBTConfigration.EXECUTE_ID_FACTORY + " error", e);
        }
    }

    public static WorkflowContextFactory getInstance() {
        if (factory == null) {
            synchronized (WorkflowContextFactory.class) {
                if (factory == null) {
                    factory = new WorkflowContextFactory();
                }
            }
        }
        return factory;
    }

    public IWorkflowConext createWorkflowContext(String workflowId) {
        WorkflowContext context = new WorkflowContext(workflowId);
        // 设置执行id
        String contextId = idFactory.createExecuteId(workflowId);
        IContextProperty<String> p = ContextPropertyFactory.getInstance()
                .createPrivateConstant(IWorkflowContextConstants.WORKFLOW_CONTEXT_ID);
        p.setValue(contextId);
        context.setContextProperty(p);
        logger.debug("instance context id [ " + contextId + "]");

        // 获取工作流指令集
        InstructionSet task = WorkflowContainerManager.getInstance()
                .getWorkflowInstruction(workflowId);
        if (task == null) {
            throw new RuntimeException(
                    "the workflow Instruction  been finding is not exsit : "
                            + workflowId);
        }
        context.setInstructionSet(task);
        return context;
    }

    public IWorkflowConext createWorkflowContext() {
        WorkflowContext context = new WorkflowContext();
        //设置执行id
        String contextId = idFactory.createExecuteId("");
        IContextProperty<String> p = ContextPropertyFactory.getInstance()
                .createPrivateConstant(IWorkflowContextConstants.WORKFLOW_CONTEXT_ID);
        p.setValue(contextId);
        context.setContextProperty(p);
        logger.debug("instance context id [ " + contextId + "]");

        return context;
    }
}
